#include "leos_def.h"

struct exception_stack_frame {
    le_uint32_t r0;
    le_uint32_t r1;
    le_uint32_t r2;
    le_uint32_t r3;
    le_uint32_t r12;
    le_uint32_t lr;
    le_uint32_t pc;
    le_uint32_t psr;
};

struct stack_frame {
    le_uint32_t r4;
    le_uint32_t r5;
    le_uint32_t r6;
    le_uint32_t r7;
    le_uint32_t r8;
    le_uint32_t r9;
    le_uint32_t r10;
    le_uint32_t r11;

    struct exception_stack_frame exception_stack_frame;
};

le_uint32_t le_thread_switch_interrupt_flag;
le_uint32_t le_sp_from_thread, le_sp_to_thread;

le_uint8_t *le_hw_stack_init(void *thread_entry,
                             void *thread_parameter,
                             le_uint8_t *stack_addr,
                             void *thread_exit)
{
    struct stack_frame *stack_frame = LE_NULL;
    le_uint8_t *psp = LE_NULL;

    psp = stack_addr;
    psp = (le_uint8_t *)LE_ALIGN_DOWN((le_uint32_t)psp, 8);
    psp -= sizeof(struct stack_frame);

    stack_frame = (struct stack_frame *)psp;

    for (int i = 0; i < sizeof(struct stack_frame) / sizeof(le_uint32_t); i++) {
        ((le_uint32_t *)stack_frame)[i] = 0xdeadbeaf;
    }

    stack_frame->exception_stack_frame.r0 = (unsigned long)thread_parameter;
    stack_frame->exception_stack_frame.r1 = 0;
    stack_frame->exception_stack_frame.r2 = 0;
    stack_frame->exception_stack_frame.r3 = 0;
    stack_frame->exception_stack_frame.r12 = 0;
    stack_frame->exception_stack_frame.lr = (unsigned long)thread_exit;
    stack_frame->exception_stack_frame.pc = (unsigned long)thread_entry;
    stack_frame->exception_stack_frame.psr = 0x01000000L;

    return psp;
}



